package com.yunhe.device.utils;

import com.github.andrewoma.dexx.collection.internal.hashmap.ListMap;
import com.yunhe.common.utils.AliOssApiUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName EquipmentController
 * @Description TODO
 * @Author HeTao
 * @Date 2021/11/15 13:36
 * @Version 1.0
 **/
public class UploadUtil {

    /**
     * 读取文件内容到map
     * @param file
     * @return
     * @throws IOException
     */
    public static Map<String, Map<Integer, Map<String, String>>> readExcelToMap(MultipartFile file,int startRow,int pageSize,int headRowCount,int dataRow) throws IOException {

        Workbook wb = null;
        Sheet sheet = null;
        Row row = null;
        Row headRow = null;
        // 声明所有页的集合
        Map<String, Map<Integer, Map<String, String>>> mapSheet = new LinkedHashMap<>();
        try {
            //读取文档
            wb = readExcel(file);
            if (wb != null) {
                // 获取总页数
                for (int i = 0; i < pageSize; i++) {

                    // 声明当前页的行和列
                    Map<Integer, Map<String, String>> map = new HashMap<>();
                    // 获取当前页
                    sheet = wb.getSheetAt(i);
                    //声明当前页图片的集合
                    Map<String, PictureData> pMap = null;
                    //获取当前页的所有图片
                    if(file.getOriginalFilename().endsWith(".xls")){
                        //用于区分 没写方法重载
                        pMap = getPictures1((HSSFSheet) sheet);
                    }else{
                        //用于区分 没写方法重载
                        pMap = getPictures2((XSSFSheet) sheet);
                    }
                    //获取页名称
                    String sheetName = sheet.getSheetName();

                    //获取当前页的最大行数
                    int rowSize = sheet.getPhysicalNumberOfRows();
                    headRow = sheet.getRow(headRowCount);
                    //获取当前页的最大列数;
                    int columnSize = headRow.getPhysicalNumberOfCells();
                    for (int j = startRow; j < rowSize; j++) {
                        row = sheet.getRow(j);
                        if(j >= 2){
                            // 声明当前列
                            Map<String, String> columnMap = new HashMap<>();
                            //System.out.println("列大小:"+columnSize);
                            for (int k = 0; k < columnSize; k++) {
                                String value = getCellValue(row.getCell(k));
                                // 添加当前列的内容 j2代表第几列 value是内容
                                columnMap.put(getCellValue(headRow.getCell(k))+"name-"+k, value);

                            }
                            // 添加当前行的内容 j代表第几行 value是列的内容 意思是第几行第几列的内容
                            map.put(j, columnMap);
                        }
                    }
                    //解析图片并上传到服务器 进行文件上传后 返回上传地址 并根据图片所在的表格位置 赋值表格位置为 上传后的返回地址
                    Object key[] = pMap.keySet().toArray();
                    //上传图片 阿里云上传图片
                    for (int v = 0; v < pMap.size(); v++) {
                        //获取图像数据对象
                        PictureData pic = pMap.get(key[v]);
                        //图片数据
                        byte[] data = pic.getData();

                        //获取文件名称
                        String picName = key[v].toString();

                        //获取文件后缀名
                        String ext = pic.suggestFileExtension();

                        //=============本地测试图片上传开始==============
                        String imageFileName = picName+"."+ext;
                        File picFile = new File(imageFileName);
                        FileOutputStream out = new FileOutputStream(picFile);
                        out.write(data);
                        out.flush();
                        //=============本地测试图片上传结束==============
                        //===============阿里云上传图片上传开始==============
                        String imgToCos = AliOssApiUtils.putObjectByte(picFile);
                        //===============阿里云上传图片上传结束==============

                        //解析key 并根据key 设置 某一行的某一列的 图片链接
                        String[] split = picName.split("-");
                        Integer rowIndex = Integer.parseInt(split[0].toString()),columnIndex = Integer.parseInt(split[1].toString());
                        //根据行下标 获取所有的列
                        Map<String, String> columns = map.get(rowIndex);

                        //根据列下标 设置图片链接值
                        //参数2为图片上传后的路径
                        columns.put(getCellValue(headRow.getCell(columnIndex))+"name-"+columnIndex, imgToCos);
                        out.close();
                    }
                    // 添加当前页的所有内容
                    mapSheet.put(sheetName, map);
                }
            }
            return mapSheet;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }



    // 读取excel
    private static Workbook readExcel(MultipartFile file) {
        Workbook wb = null;
        if (file == null) {
            return null;
        }
        String originalFilename = file.getOriginalFilename();
        String extString = originalFilename.substring(originalFilename.lastIndexOf("."));
        InputStream is = null;
        try {
            is = file.getInputStream();
            if (".xls".equals(extString)) {
                return wb = new HSSFWorkbook(is);
            } else if (".xlsx".equals(extString)) {
                return wb = new XSSFWorkbook(is);
            } else {
                return wb = null;
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return wb;
    }

    // 读取图片
    public static Map<String, PictureData> getPictures1(HSSFSheet sheet) throws IOException {
        Map<String, PictureData> map = new HashMap<String, PictureData>();
        HSSFPatriarch drawingPatriarch = sheet.getDrawingPatriarch();
        if(drawingPatriarch != null){
            List<HSSFShape> list = drawingPatriarch.getChildren();
            for (HSSFShape shape : list) {

                if (shape instanceof HSSFPicture) {
                    HSSFPicture picture = (HSSFPicture) shape;

                    HSSFClientAnchor cAnchor = (HSSFClientAnchor) picture.getAnchor();
                    PictureData pdata = picture.getPictureData();
                    String key = cAnchor.getRow1() + "-" + cAnchor.getCol1(); // 行号-列号
                    map.put(key, pdata);
                }
            }
        }
        return map;
    }

    //读取图片
    public static Map<String, PictureData> getPictures2(XSSFSheet sheet) throws IOException {
        Map<String, PictureData> map = new HashMap<String, PictureData>();
        List<POIXMLDocumentPart> list = sheet.getRelations();
        for (POIXMLDocumentPart part : list) {
            if (part instanceof XSSFDrawing) {
                XSSFDrawing drawing = (XSSFDrawing) part;
                List<XSSFShape> shapes = drawing.getShapes();
                for (XSSFShape shape : shapes) {
                    XSSFPicture picture = (XSSFPicture) shape;
                    XSSFClientAnchor anchor = picture.getPreferredSize();
                    CTMarker marker = anchor.getFrom();
                    String key = marker.getRow() + "-" + marker.getCol();
                    map.put(key, picture.getPictureData());
                }
            }
        }
        return map;
    }

    public static String getCellValue(Cell cell) {
        Object result = "";
        if (cell == null) { return "";}
        // 注意：一定要设成这个，否则可能会出现乱码
        //cell.setEncoding(HSSFCell.ENCODING_UTF_16);
        switch (cell.getCellType()) {
            case STRING:
                result = cell.getStringCellValue();
                break;
            case NUMERIC:
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    Date date = cell.getDateCellValue();
                    if (date != null) {
                        result = new SimpleDateFormat("yyyy-MM-dd")
                                .format(date);
                    } else {
                        result = "";
                    }
                } else {
                    //经纬度要6位
                    result = new DecimalFormat("##.######").format(cell
                            .getNumericCellValue());
                }
                break;
            case FORMULA:
                cell.setCellType(CellType.FORMULA);
                result = cell.getStringCellValue();
                break;
            case BLANK:
                break;
            case ERROR:
                result = "";
                break;
            case BOOLEAN:
                result = (cell.getBooleanCellValue() == true ? "Y"
                        : "N");
                break;
            default:
                result = "";
        }

        return result.toString();
    }

    public static void printImg(Map<String, PictureData> sheetList) throws IOException {

        Object key[] = sheetList.keySet().toArray();
        for (int i = 0; i < sheetList.size(); i++) {
            PictureData pic = sheetList.get(key[i]);
            String picName = key[i].toString();
            String ext = pic.suggestFileExtension();
            byte[] data = pic.getData();
            FileOutputStream out = new FileOutputStream("D:\\" + picName + "." + ext);
            out.write(data);
            out.flush();
            out.close();
        }
    }
//    //根据路径去腾讯云判断当前图片是否存在
//    public static boolean hasImage(String key){
//        CosClientUtil cosClientUtil = new CosClientUtil();
//        ObjectMetadata objectMetadata = cosClientUtil.getObjectMetadata(key);
//        if (objectMetadata != null) {
//            System.out.println("objectMetadata存在！");
//            return true;
//        }
//        return false;
//    }
}

